#!/usr/bin/env bash

main() {
	local SCRIPT_NAME SCRIPT_DIR
	SCRIPT_NAME="$(basename "$0")"
	SCRIPT_DIR="$(dirname "$(realpath "$0")")"
	# shellcheck source=src/lib/rsdk/utils.sh
	source "$SCRIPT_DIR/../../lib/rsdk/utils.sh"

	local TEMP
	if ! TEMP="$(getopt -o "h" -l "help" -n "$0" -- "$@")"; then
		return
	fi
	eval set -- "$TEMP"

	while true; do
		TEMP="$1"
		shift
		case "$TEMP" in
		-h | --help)
			rsdk help "${SCRIPT_NAME#rsdk-}"
			return
			;;
		--)
			break
			;;
		*)
			error "$EXIT_UNKNOWN_OPTION" "$TEMP"
			;;
		esac
	done

	if (($# == 0)); then
		"$0" --help
		return
	fi

	if [[ -f "/.dockerenv" ]]; then
		error "$EXIT_RUNNING_IN_CONTAINER"
	fi

	if [[ $SCRIPT_NAME == "rsdk-chroot" ]] && (($# < 1)); then
		error "$EXIT_TOO_FEW_ARGUMENTS"
	elif [[ $SCRIPT_NAME == "rsdk-install" ]] && (($# < 2)); then
		error "$EXIT_TOO_FEW_ARGUMENTS"
	fi

	disk="$1"
	shift

	RSDK_TEMP="$(mktemp -d)"

	if [[ -f $disk ]]; then
		disk_file="$disk"
		trap 'set +e; sudo -n true && (sudo umount -R "$RSDK_TEMP"; sudo kpartx -d "$disk_file"; sync); rm -rf "$RSDK_TEMP"' SIGINT SIGQUIT SIGTSTP EXIT
		sudo kpartx -a "$disk"
		echo "Target is a file. Trying to find rootfs partition..."
		if ! disk="$(sudo blkid -t LABEL=rootfs -o device | grep /dev/mapper/loop | tail -n 1)" &&
			! disk="$(sudo blkid -t PARTLABEL=rootfs -o device | grep /dev/mapper/loop | tail -n 1)" &&
			! disk="$(sudo blkid -t LABEL=opi_root -o device | grep /dev/mapper/loop | tail -n 1)"; then
			error "$EXIT_BLKDEV_NO_ROOTDEV" "$disk_file"
		fi
		disk="${disk%p*}p"
	fi

	if [[ ! -d $disk ]] && [[ ! -b $disk ]] && [[ $disk != /dev/mapper/loop* ]]; then
		error "$EXIT_NOT_BLOCK_DEVICE" "$disk"
	fi

	if [[ -b "$disk"5 ]]; then
		# legacy debos-radxa image
		sudo mount "$disk"5 "$RSDK_TEMP"
		sudo mount "$disk"4 "$RSDK_TEMP/boot"
	elif [[ -b "$disk"3 ]]; then
		# latest rbuild/rsdk image
		sudo mount "$disk"3 "$RSDK_TEMP"
		sudo mount "$disk"2 "$RSDK_TEMP/boot/efi"
		sudo mount "$disk"1 "$RSDK_TEMP/config"
	elif [[ -b "$disk"2 ]]; then
		sudo mount "$disk"2 "$RSDK_TEMP"
		case "$(sudo blkid "$disk"1 -s LABEL -o value)" in
		"armbi_boot" | "opi_boot" | "boot")
			# new armbian image / Orange Pi / Rockchip SDK image
			sudo mount "$disk"1 "$RSDK_TEMP/boot"
			;;
		*)
			# old rbuild image
			sudo mount "$disk"1 "$RSDK_TEMP/config"
			;;
		esac
	elif [[ -b "$disk"1 ]]; then
		# old armbian image
		sudo mount "$disk"1 "$RSDK_TEMP"
	elif [[ -d $disk ]]; then
		# actually a rootfs directory
		sudo mount --bind "$disk" "$RSDK_TEMP"
	else
		error "$EXIT_BLKDEV_NO_ROOTDEV" "$disk"
	fi

	case "$SCRIPT_NAME" in
	rsdk-chroot)
		sudo systemd-nspawn -D "$RSDK_TEMP" /usr/bin/bash -c "PATH=/usr/bin:/usr/sbin:/bin:/sbin bash"
		;;
	rsdk-install)
		file="${1:-}"
		ext="${file##*.}"
		case "$ext" in
		deb)
			sudo cp "$file" "$RSDK_TEMP"
			sudo systemd-nspawn -D "$RSDK_TEMP" /usr/bin/bash -c \
				"export PATH=/usr/bin:/usr/sbin:/bin:/sbin;
				if ! dpkg -i '/$(basename "$file")'; then
					apt-get install -y --fix-missing --allow-downgrades || (
						apt-get update;
						apt-get install -y --fix-missing --fix-broken --allow-downgrades
					);
				fi"
			;;
		dtbo)
			sudo cp "$file" "$RSDK_TEMP/boot/dtbo"
			sudo systemd-nspawn -D "$RSDK_TEMP" /usr/bin/bash -c "PATH=/usr/bin:/usr/sbin:/bin:/sbin bash -c u-boot-update"
			;;
		dtb)
			sudo find "$RSDK_TEMP/usr/lib/"linux-image-*/ -name "$(basename "$file")" -exec mv "{}" "{}.bak" \; -exec cp "$file" "{}" \;
			;;
		*)
			error "$EXIT_UNSUPPORTED_OPTION" "$file"
			;;
		esac
		;;
	esac

	sudo umount -R "$RSDK_TEMP"
	if cut -f 2 -d " " /proc/mounts | grep -q "$RSDK_TEMP"; then
		echo "Failed to umount $RSDK_TEMP. Your kernel might report some issues." >&2
		exit 1
	else
		rm -rf "$RSDK_TEMP"
		sync
	fi
}

main "$@"
